package com.lee.demonacosclient.controller;

import com.alibaba.cloud.nacos.ribbon.NacosServerList;
import com.lee.demonacosclient.feignclient.BaiduFeignClient;
import com.lee.demonacosclient.feignclient.ServiceProviderClient;
import com.lee.demonacosclient.model.MessageModel;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
 * @ClassName TestController
 * @Description TODO
 * @Author leejiliang
 * @DateTime 2020/9/19 8:36 PM
 * @Version 1.0
 */
@RestController
@RequestMapping("/client-test")
@Slf4j
public class TestController {

	@Autowired
	private DiscoveryClient discoveryClient;
	@Autowired
	private RestTemplate restTemplate;

	@Autowired
	private ServiceProviderClient serviceProviderClient;

	@Autowired
	private BaiduFeignClient baiduFeignClient;

	@Autowired
	private RocketMQTemplate rocketMQTemplate;
	/**
	 * 通过 restTemplate 直接调用指定的服务.
	 * 弊端: 无法处理服务 ip 变更的问题.
	 * @return
	 */
	@GetMapping("/1")
	public String getInfoFromProvider() {
		return restTemplate.getForObject("http://localhost:1980/test", String.class);
	}

	/**
	 * 通过 discoveryClient 发现服务
	 * 缺点: 只能用到一个服务.
	 * @return
	 */
	@GetMapping("/2")
	public String getInfoFromProviderFromNacos() {
		List<ServiceInstance> instances = discoveryClient.getInstances("service-provider");
		ServiceInstance serviceInstance = instances.stream().findAny().orElseThrow(() -> new IllegalArgumentException("未找到服务提供者."));
		return restTemplate.getForObject(serviceInstance.getUri() + "test", String.class);
	}

	/**
	 * 通过随机的方式调用服务提供者
	 * 弊端: 代码越来越多,模板代码太多了
	 * @return
	 */
	@GetMapping("/3")
	public String getInfoFromProviderUseSelfLoadBanlance() {
		List<ServiceInstance> instances = discoveryClient.getInstances("service-provider");
		int i = ThreadLocalRandom.current().nextInt(instances.size());
		String targetUrl = instances.get(i).getUri() + "test";
		return restTemplate.getForObject(targetUrl, String.class);
	}

	/**
	 * 使用 spring 提供的 loadBanlance 来实现负载均衡, 需要在创建 RestTemplate 时, 指定@LoadBanlanced 注解
	 * @return
	 */
	@GetMapping("/4")
	public String getInfoFromProviderUseSpringLoadBanlance() {
		String targetUrl = "http://service-provider/test";
		return restTemplate.getForObject(targetUrl, String.class);
	}

	/**
	 * 使用 Feign 的方式调用
	 * @return
	 */
	@GetMapping("/5")
	public String getInfoByFeign() {
		return serviceProviderClient.getTest();
	}

	/**
	 * 脱离 ribbon 随便调用一个网址
	 * @return
	 */
	@GetMapping("/6")
	public String getInfoFromBaidu() {
		return baiduFeignClient.index();
	}

	@GetMapping("/7")
	public void publishMessage() {
		rocketMQTemplate.convertAndSend("finance", MessageModel.builder().name("test").age(18).build());
		log.info("发送一条消息");
	}

}
